package de.zainodis.triplog.data;

import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;

import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;

import java.util.ArrayList;
import java.util.List;

import de.zainodis.triplog.data.persistence.IDiaryDao;
import de.zainodis.triplog.data.share.TriplogContract;
import de.zainodis.triplog.util.Utilities;

/**
 * Represents a diary entry for a given day. There is only one entry per day. If an entry has been saved already it can still be edited and updated.
 * Created by fzarrai on 9/9/2014.
 */
@DatabaseTable(tableName = IDiaryDao.TABLE_NAME, daoClass = IDiaryDao.DiaryDao.class)
public class DiaryEntry implements ICrudOperations, Parcelable {
    private static final String TAG = "Weather";

    @DatabaseField(generatedId = true, columnName = IDiaryDao.COLUMN_ID)
    private long id;
    @DatabaseField(columnName = IDiaryDao.COLUMN_FK_TRIP_ID)
    private long fkTripEntry;
    @DatabaseField(columnName = IDiaryDao.COLUMN_DATE)
    private String date;
    @DatabaseField(columnName = IDiaryDao.COLUMN_TEXT)
    private String text;

    public DiaryEntry() {
    }

    public DiaryEntry(ContentValues values) {
        id = Utilities.getAsLong(values, IDiaryDao.COLUMN_ID);
        fkTripEntry = Utilities.getAsLong(values, IDiaryDao.COLUMN_FK_TRIP_ID);
        date = Utilities.getAsString(values, IDiaryDao.COLUMN_DATE);
        text = Utilities.getAsString(values, IDiaryDao.COLUMN_TEXT);
    }

    /**
     * @return ContentValues for this instance.
     */
    public ContentValues getContentValues() {
        ContentValues values = new ContentValues();
        values.put(IDiaryDao.COLUMN_DATE, date);
        values.put(IDiaryDao.COLUMN_FK_TRIP_ID, fkTripEntry);
        values.put(IDiaryDao.COLUMN_TEXT, text);
        if (id > 0) {
            values.put(IDiaryDao.COLUMN_ID, id);
        }

        return values;
    }

    public void setId(long id) {
        this.id = id;
    }

    public void setFkTripEntry(long fkTripEntry) {
        this.fkTripEntry = fkTripEntry;
    }

    public long getFkTripEntry() {
        return fkTripEntry;
    }

    public long getId() {
        return id;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }


    public static final Parcelable.Creator<DiaryEntry> CREATOR = new Parcelable.Creator<DiaryEntry>() {
        public DiaryEntry createFromParcel(Parcel in) {
            return new DiaryEntry(in);
        }

        public DiaryEntry[] newArray(int size) {
            return new DiaryEntry[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeLong(id);
        out.writeLong(fkTripEntry);
        out.writeString(date);
        out.writeString(text);
    }

    private DiaryEntry(Parcel in) {
        id = in.readLong();
        fkTripEntry = in.readLong();
        date = in.readString();
        text = in.readString();
    }

    @Override
    public int delete(Context context) {
        int count = 0;
        if (id > 0) {
            //Delete the weather from the database
            count = context.getContentResolver().delete(TriplogContract.CONTENT_URI_DIARY, IDiaryDao.COLUMN_ID + " = ?",
                    new String[]{String.valueOf(id)});
        }
        return count;
    }

    @Override
    public long createOrUpdate(Context context) {
        if (context == null) {
            Log.e(TAG, "Provided context is null.");
            return -1;
        }
        if(getFkTripEntry() <= 0){
            Log.e(TAG, "No foreign key trip id has been set, aborting.");
            return -1;

        }
        Cursor cursor = context.getContentResolver().query(
                TriplogContract.CONTENT_URI_DIARY, new String[]{IDiaryDao.COLUMN_ID}, IDiaryDao.COLUMN_FK_TRIP_ID + " = ? and " + IDiaryDao.COLUMN_TEXT + " = ?" ,
                new String[]{String.valueOf(getFkTripEntry()), text}, null);

        if (cursor.moveToFirst()) {
            id = cursor.getLong(cursor.getColumnIndex(IDiaryDao.COLUMN_ID));
            //Entry already exists, so run an update
            context.getContentResolver().update(TriplogContract.CONTENT_URI_DIARY, getContentValues(), IDiaryDao.COLUMN_ID + " = ?", new String[]{String.valueOf(getId())});
        } else {
            //No entry found yet, hence insert
            Uri uri = context.getContentResolver().insert(TriplogContract.CONTENT_URI_DIARY, getContentValues());
            //Return id of the inserted trip instance
            id = ContentUris.parseId(uri);
        }

        return id;
    }

    /**
     * @param id trip id.
     * @return the diary entries linked to the given trip id; an empty list if there are none.
     */
    public static List<DiaryEntry> getByTripId(Context context, long id) {
        Cursor cursor = context.getContentResolver().query(
                TriplogContract.CONTENT_URI_DIARY, null, IDiaryDao.COLUMN_FK_TRIP_ID + " = ?",
                new String[]{String.valueOf(id)},
                null);
        List<DiaryEntry> result = new ArrayList<DiaryEntry>();
        while (cursor.moveToNext()) {
            DiaryEntry entry = new DiaryEntry();
            entry.setFkTripEntry(id);
            entry.setId(cursor.getLong(cursor.getColumnIndex(IDiaryDao.COLUMN_ID)));
            entry.setDate(cursor.getString(cursor.getColumnIndex(IDiaryDao.COLUMN_DATE)));
            entry.setText(cursor.getString(cursor.getColumnIndex(IDiaryDao.COLUMN_TEXT)));
            result.add(entry);
        }
        return result;
    }
}
